SPB Git forge

spb/cancerindex

Public
37commits 1branches 0releases
2.9 MBsize
maindefault branch
10 days agolast push
TypeScript 97.2% SQL 1.5% CSS 0.6% JavaScript 0.5%
26.2 KB · 444 lines tsx
Raw Blame History
1import type { Metadata } from 'next';2import Link from 'next/link';3import { notFound, permanentRedirect } from 'next/navigation';4import { ExternalLink } from 'lucide-react';5import { PageHeader, Section, KV, Note } from '@/components/ui/section';6import { Badge, ClaimBadge } from '@/components/ui/badge';7import { EmptyState } from '@/components/ui/empty-state';8import { Freshness } from '@/components/ui/freshness';9import { Pager } from '@/components/ui/pager';10import { SourceBadge } from '@/components/ui/source-badge';11import { ApprovalsTable } from '@/components/data/approvals-table';12import { EvidenceTable } from '@/components/data/evidence-table';13import { TrialTable } from '@/components/data/trial-list';14import { PublicationList } from '@/components/data/publication-list';15import { GraphLink } from '@/components/graph/graph-link';16import {17  getBiomarkerBySlug,18  biomarkerGenes,19  biomarkerVariants,20  biomarkerCancers,21  biomarkerDrugs,22  biomarkerEvidence,23  biomarkerEvidenceCount,24  biomarkerApprovals,25  biomarkerTrialCounts,26  biomarkerActiveTrials,27  literatureScope,28  noScopeReason,29  kindLabel,30  BIOMARKER_LINKS_FORMULA,31} from '@/lib/queries/biomarkers';32import { EVIDENCE_PAGE_SIZE, EVIDENCE_LEVEL_LABEL } from '@/lib/queries/evidence';33import { TRIAL_PAGE_SIZE } from '@/lib/queries/trials';34import { recentPublicationsFor, recentPublicationsForCount, PUBLICATION_PAGE_SIZE } from '@/lib/queries/publications';35import { loadProvenance } from '@/lib/queries/provenance';36import { jsonLd } from '@/lib/seo';37import { SITE_URL } from '@/lib/site';38import { fmtDate, fmtInt, humanize } from '@/lib/format';39import { pageInfo } from '@/lib/pagination';40import { int, str, withParams, type SP } from '@/lib/search-params';4142export const revalidate = 3600;4344export async function generateMetadata({ params }: { params: Promise<{ slug: string }> }): Promise<Metadata> {45  const b = await getBiomarkerBySlug((await params).slug);46  return b ? { title: `${b.name} — biomarker`, description: b.description ?? `${b.name}: what is measured, associated cancers, drugs with predictive evidence, approvals and trials.`, alternates: { canonical: `/biomarker/${b.slug}` } } : { title: 'Biomarker' };47}4849const EVS = (code: string) => `https://evsexplore.semantics.cancer.gov/evsexplore/concept/ncit/${code}`;5051export default async function BiomarkerPage({ params, searchParams }: { params: Promise<{ slug: string }>; searchParams: Promise<SP> }) {52  const { slug } = await params;53  const b = await getBiomarkerBySlug(slug);54  if (!b) notFound();55  if (b.slug !== slug) permanentRedirect(`/biomarker/${b.slug}`);56  const sp = await searchParams;57  const m = b.measurement;58  const hasScope = b.gene_ids.length > 0 || b.variant_ids.length > 0;59  const reason = noScopeReason(b);60  const lit = literatureScope(b);6162  const [evTotal, trialCounts, pTotal] = await Promise.all([hasScope ? biomarkerEvidenceCount(b, 'PREDICTIVE') : Promise.resolve(0), hasScope ? biomarkerTrialCounts(b) : Promise.resolve({ total: 0, active: 0, recruiting: 0, phase3: 0 }), lit.ids.length ? recentPublicationsForCount(lit.entityType, lit.ids) : Promise.resolve(0)]);63  const ev = pageInfo(int(sp, 'evPage', 1, 1, 100_000), EVIDENCE_PAGE_SIZE, evTotal);64  const tp = pageInfo(int(sp, 'tPage', 1, 1, 100_000), TRIAL_PAGE_SIZE, trialCounts.active);65  const pp = pageInfo(int(sp, 'pPage', 1, 1, 100_000), PUBLICATION_PAGE_SIZE, pTotal);66  const aPage = int(sp, 'aPage', 1, 1, 100_000);6768  const [genes, variants, cancers, drugs, evidence, approvals, trials, pubs] = await Promise.all([69    biomarkerGenes(b),70    biomarkerVariants(b),71    hasScope ? biomarkerCancers(b) : Promise.resolve([]),72    hasScope ? biomarkerDrugs(b) : Promise.resolve([]),73    evTotal ? biomarkerEvidence(b, { type: 'PREDICTIVE', page: ev.page, pageSize: ev.pageSize }) : Promise.resolve([]),74    biomarkerApprovals(b),75    trialCounts.active ? biomarkerActiveTrials(b, { page: tp.page, pageSize: tp.pageSize }) : Promise.resolve([]),76    pTotal ? recentPublicationsFor(lit.entityType, lit.ids, { page: pp.page, pageSize: pp.pageSize }) : Promise.resolve([]),77  ]);78  const prov = await loadProvenance([...evidence.map((e) => e.provenance_id), ...approvals.map((a) => a.provenance_id)]);7980  const jurisdictions = [...new Set(approvals.map((a) => a.jurisdiction))].sort();81  const wanted = str(sp, 'jurisdiction');82  const selected = jurisdictions.includes(wanted) ? wanted : null;83  const shownApprovals = selected ? approvals.filter((a) => a.jurisdiction === selected) : approvals;84  const tumorAgnosticRows = approvals.filter((a) => a.tumor_agnostic);85  const byIndication = approvals.filter((a) => a.matched_by === 'indication').length;8687  const current = { jurisdiction: selected ?? '', evPage: ev.page > 1 ? ev.page : '', tPage: tp.page > 1 ? tp.page : '', pPage: pp.page > 1 ? pp.page : '', aPage: aPage > 1 ? aPage : '' };88  const href = (o: Record<string, string | number | null | undefined>, hash?: string) => `/biomarker/${b.slug}${withParams(current, o)}${hash ? `#${hash}` : ''}`;89  const aliases = m.aliases ?? [];9091  const ld: Record<string, unknown> = { '@context': 'https://schema.org', '@type': 'MedicalTest', name: b.name, url: `${SITE_URL}/biomarker/${b.slug}` };92  if (b.description) ld.description = b.description;93  if (aliases.length) ld.alternateName = aliases.slice(0, 20);94  if (b.ncit_code) ld.code = [{ '@type': 'MedicalCode', codeValue: b.ncit_code, codingSystem: 'NCIt' }];95  if (m.assays?.length) ld.usesDevice = m.assays.map((a) => ({ '@type': 'MedicalDevice', name: a }));9697  const computedNote = (rule: string) => (98    <span className="inline-flex flex-wrap items-center gap-1.5 text-[12px] text-ink-3">99      <ClaimBadge kind="computed" />100      <span title={rule}>101        rule <span className="ci-mono">{BIOMARKER_LINKS_FORMULA}</span>102      </span>103    </span>104  );105106  return (107    <article>108      <script type="application/ld+json" dangerouslySetInnerHTML={{ __html: jsonLd(ld) }} />109      <PageHeader kicker={`Biomarker · ${kindLabel(b.kind)}`} title={b.name} lede={b.description ?? undefined}>110        <p className="mt-2 flex flex-wrap items-center gap-2 text-[12.5px]">111          <span className="ci-mono text-ink-3">{b.id}</span>112          {genes.map((g) => (113            <span key={g.id} className="inline-flex items-center gap-1">114              <Link className="ci-link ci-mono" href={`/gene/${g.symbol}`}>115                {g.symbol}116              </Link>117              <GraphLink type="gene" entityRef={g.symbol} label="graph →" />118            </span>119          ))}120          {b.ncit_code ? (121            <a className="ci-link inline-flex items-center gap-1" href={EVS(b.ncit_code)} target="_blank" rel="noopener noreferrer" title={m.ncit?.name ? `NCIt preferred name: ${m.ncit.name}` : undefined}>122              NCIt {b.ncit_code} <ExternalLink className="h-3 w-3" aria-hidden />123            </a>124          ) : null}125          {tumorAgnosticRows.length ? (126            <Badge tone="accent" title={`${tumorAgnosticRows.length} approval row${tumorAgnosticRows.length === 1 ? '' : 's'} flagged tumor_agnostic by the source (listed below)`}>127              Tumor-agnostic · {tumorAgnosticRows.length} approval row{tumorAgnosticRows.length === 1 ? '' : 's'}128            </Badge>129          ) : m.tumorAgnostic ? (130            <Badge tone="outline" title="Curated flag: an FDA tissue-agnostic indication exists for this marker, but no approval row with tumor_agnostic = true is ingested yet">131              Tumor-agnostic (curated) · no approval row ingested yet132            </Badge>133          ) : null}134        </p>135        {aliases.length ? (136          <p className="mt-1 text-[12.5px] text-ink-3">137            <span className="ci-kicker mr-2">Also called</span>138            {aliases.join(' · ')}139          </p>140        ) : null}141      </PageHeader>142143      {tumorAgnosticRows.length ? (144        <section id="tumor-agnostic" aria-labelledby="tumor-agnostic-title" className="ci-rule mb-6 pt-4">145          <p className="ci-kicker mb-1">Tissue-agnostic indications</p>146          <h2 id="tumor-agnostic-title" className="text-lg">147            Approval rows flagged tumor-agnostic ({tumorAgnosticRows.length})148          </h2>149          <ul className="ci-rows mt-2">150            {tumorAgnosticRows.map((a) => (151              <li key={a.id}>152                <span>153                  <Link className="ci-link" href={`/drug/${a.drug_slug}#approvals`}>154                    {a.drug_name}155                  </Link>{' '}156                  <span className="ci-mono">{a.jurisdiction}</span> <span className="text-ink-3">{a.authority}</span> · {fmtDate(a.approval_date)} · <Badge tone="outline">{a.matched_by === 'indication' ? 'matched on indication text' : a.matched_by === 'both' ? 'drug + indication text' : 'drug in derived set'}</Badge>157                </span>158                <span className="text-[12px] text-ink-3">159                  <ClaimBadge kind="regulatory" /> {a.status}160                </span>161              </li>162            ))}163          </ul>164          <p className="mt-2 text-[12px] text-ink-3">The flag is the source's (openFDA label text), never inferred; the full indication text of each row is in the Approvals section below.</p>165        </section>166      ) : null}167168      <div className="grid gap-8 lg:grid-cols-[1fr_320px]">169        <div className="space-y-8">170          <Section id="cancers" kicker="Derived" title={`Associated cancers (${fmtInt(cancers.length)})`} description="Cancers mapped in ACCEPTED CIViC predictive, prognostic or diagnostic items whose variant (molecular markers) or gene (gene-level markers) is in this biomarker's scope. Counts by type and native level; each row links to the cancer's evidence tab." actions={computedNote('Associated cancers = distinct mapped cancer_id of in-scope CIViC evidence (status ACCEPTED; types PREDICTIVE, PROGNOSTIC, DIAGNOSTIC).')}>171            {cancers.length ? (172              <div className="ci-table-wrap">173                <table className="ci-table">174                  <thead>175                    <tr>176                      <th scope="col">Cancer</th>177                      <th scope="col" className="num">Items</th>178                      <th scope="col" className="num">Predictive</th>179                      <th scope="col" className="num">Prognostic</th>180                      <th scope="col" className="num">Diagnostic</th>181                      <th scope="col" title="CIViC evidence levels as curated: A validated · B clinical · C case study · D preclinical · E inferential">Levels A / B / C / D / E</th>182                    </tr>183                  </thead>184                  <tbody>185                    {cancers.map((c) => (186                      <tr key={c.cancer_id}>187                        <td className="min-w-[220px]">188                          <Link className="ci-link" href={`/cancer/${c.slug}/evidence`}>189                            {c.name}190                          </Link>191                        </td>192                        <td className="num">{fmtInt(c.n)}</td>193                        <td className="num">{c.predictive || '—'}</td>194                        <td className="num">{c.prognostic || '—'}</td>195                        <td className="num">{c.diagnostic || '—'}</td>196                        <td className="ci-num whitespace-nowrap text-[12.5px]">197                          {[c.level_a, c.level_b, c.level_c, c.level_d, c.level_e].map((n, i) => (198                            <span key={i} className={n ? '' : 'text-ink-4'} title={EVIDENCE_LEVEL_LABEL[['A', 'B', 'C', 'D', 'E'][i]!]}>199                              {i > 0 ? ' / ' : ''}200                              {n}201                            </span>202                          ))}203                        </td>204                      </tr>205                    ))}206                  </tbody>207                </table>208              </div>209            ) : (210              <EmptyState compact knows={genes.map((g) => ({ label: `Gene ${g.symbol}`, href: `/gene/${g.symbol}` }))}>211                {reason ?? 'No ACCEPTED CIViC predictive, prognostic or diagnostic item maps a cancer to this biomarker yet.'}212              </EmptyState>213            )}214          </Section>215216          <Section id="drugs" kicker="Derived" title={`Drugs with predictive evidence (${fmtInt(drugs.length)})`} description="Therapies named in in-scope PREDICTIVE CIViC items, plus targets of PREDICTS_RESPONSE_TO knowledge edges from in-scope variants. Sensitivity and resistance are counted separately and never merged into a verdict." actions={computedNote('Drug set = therapy_ids of in-scope PREDICTIVE evidence ∪ targets of active PREDICTS_RESPONSE_TO knowledge edges whose source variant is in scope.')}>217            {drugs.length ? (218              <>219                <div className="ci-table-wrap">220                  <table className="ci-table">221                    <thead>222                      <tr>223                        <th scope="col">Drug</th>224                        <th scope="col" className="num" title="PREDICTIVE CIViC items in scope naming this therapy">CIViC items</th>225                        <th scope="col" className="num" title="Items with significance SENSITIVITY/RESPONSE">Sensitivity</th>226                        <th scope="col" className="num" title="Items with significance RESISTANCE">Resistance</th>227                        <th scope="col" title="Best (lowest letter) native CIViC level among those items">Best level</th>228                        <th scope="col" className="num" title="Active PREDICTS_RESPONSE_TO knowledge edges (sensitivity / resistance)">Edges (S / R)</th>229                        <th scope="col">Cancer context</th>230                      </tr>231                    </thead>232                    <tbody>233                      {drugs.map((d) => (234                        <tr key={d.drug_id}>235                          <td className="min-w-[180px]">236                            <Link className="ci-link font-medium" href={`/drug/${d.slug}`}>237                              {d.name}238                            </Link>239                            {d.kind ? <span className="block text-[11px] text-ink-3">{humanize(d.kind)}</span> : null}240                          </td>241                          <td className="num">{d.evidence_n || '—'}</td>242                          <td className="num">{d.sensitivity ? <Badge tone="ok">{d.sensitivity}</Badge> : '—'}</td>243                          <td className="num">{d.resistance ? <Badge tone="danger">{d.resistance}</Badge> : '—'}</td>244                          <td>{d.best_level ? <abbr title={EVIDENCE_LEVEL_LABEL[d.best_level] ?? d.best_level}>{d.best_level}</abbr> : '—'}</td>245                          <td className="num ci-num">246                            {d.edge_n ? (247                              <>248                                {d.edge_sensitivity} / {d.edge_resistance}249                              </>250                            ) : (251                              '—'252                            )}253                          </td>254                          <td className="max-w-[360px] text-[12.5px]">255                            {d.cancer_slugs.length ? (256                              d.cancer_slugs.slice(0, 4).map((s, i) => (257                                <span key={s}>258                                  {i > 0 ? ', ' : ''}259                                  <Link className="ci-link" href={`/cancer/${s}`}>260                                    {d.cancer_names[i]}261                                  </Link>262                                </span>263                              ))264                            ) : (265                              <span className="text-ink-3">—</span>266                            )}267                            {d.cancer_slugs.length > 4 ? <span className="text-ink-3"> +{d.cancer_slugs.length - 4}</span> : null}268                          </td>269                        </tr>270                      ))}271                    </tbody>272                  </table>273                </div>274                <div className="mt-2 flex flex-wrap items-center gap-1.5 text-[12px] text-ink-3">275                  <ClaimBadge kind="curated" />276                  <SourceBadge p={{ sourceSlug: 'civic', sourceName: 'CIViC', layer: 'canonical' }} /> items and knowledge edges as curated at the source.277                </div>278              </>279            ) : (280              <EmptyState compact>{reason ?? 'No PREDICTIVE CIViC item or knowledge edge links a therapy to this biomarker yet.'}</EmptyState>281            )}282          </Section>283284          <Section id="evidence" kicker="Curated evidence" title={`Predictive evidence items (${fmtInt(evTotal)})`} description={`ACCEPTED CIViC predictive items in scope, grouped by molecular profile and therapy with native level, direction and cancer context. ${EVIDENCE_PAGE_SIZE} per page.`}>285            {evidence.length ? (286              <>287                <EvidenceTable288                  items={evidence}289                  prov={prov}290                  showCancer291                  summary={292                    <>293                      Showing {fmtInt(ev.from)}–{fmtInt(ev.to)} of {fmtInt(evTotal)} evidence items294                    </>295                  }296                />297                <Pager total={evTotal} pageSize={ev.pageSize} page={ev.page} hrefFor={(p) => href({ evPage: p > 1 ? p : '' }, 'evidence')} label="Evidence pages" noun="evidence items" />298              </>299            ) : (300              <EmptyState compact>{reason ?? 'No ACCEPTED predictive evidence item in scope.'}</EmptyState>301            )}302          </Section>303304          <Section id="approvals" kicker="Regulatory" title={`Approvals mentioning the linked drugs (${fmtInt(approvals.length)})`} description="Approval records of the derived drug set, plus records whose indication text names this biomarker. Each record names its authority, jurisdiction, indication text and status — a drug approved in one jurisdiction for one indication is not 'approved' in general, and an approval listed here is not necessarily restricted to this biomarker." actions={computedNote(`Approvals = drug_approvals rows whose drug is in the derived set (matched by drug) or whose indication text contains a curated phrase (${(m.indicationTerms ?? []).join(' | ') || 'none'}).`)}>305            {approvals.length ? (306              <>307                <nav aria-label="Jurisdiction" className="mb-3 flex flex-wrap gap-1.5 text-[12.5px]">308                  <Link href={href({ jurisdiction: '', aPage: '' }, 'approvals')} aria-current={!selected ? 'page' : undefined} className="ci-chip">309                    All310                  </Link>311                  {jurisdictions.map((j) => (312                    <Link key={j} href={href({ jurisdiction: j, aPage: '' }, 'approvals')} aria-current={selected === j ? 'page' : undefined} className="ci-chip ci-mono">313                      {j}314                    </Link>315                  ))}316                </nav>317                <ApprovalsTable rows={shownApprovals} prov={prov} page={aPage} hrefFor={(p) => href({ aPage: p > 1 ? p : '' }, 'approvals')} />318                <p className="mt-2 text-[12px] text-ink-3">319                  {byIndication ? `${byIndication} record${byIndication === 1 ? '' : 's'} matched on indication text only (drug not in the derived set). ` : ''}320                  Health Canada DIN rows carry no indication text and only match by drug.321                </p>322              </>323            ) : (324              <EmptyState compact knows={[{ label: 'Approvals explorer', href: '/approvals' }]}>325                No approval record reaches this biomarker through its derived drugs or indication text. Absence here is not evidence of absence: only ingested jurisdictions are covered.326              </EmptyState>327            )}328          </Section>329330          <Section id="trials" kicker="Clinical trials" title={`Active trials (${fmtInt(trialCounts.active)})`} description={hasScope ? `Trials with an active ClinicalTrials.gov status, an intervention mapped to a derived drug and a condition mapped to an associated cancer. ${fmtInt(trialCounts.recruiting)} recruiting · ${fmtInt(trialCounts.phase3)} active phase 3 · ${fmtInt(trialCounts.total)} in any status. Most recently updated first, ${TRIAL_PAGE_SIZE} per page.` : undefined} actions={computedNote('Trials = clinical_trials with trial_interventions.drug_id in the derived drug set AND trial_conditions.cancer_id in the associated cancers; active = RECRUITING, NOT_YET_RECRUITING, ENROLLING_BY_INVITATION, ACTIVE_NOT_RECRUITING.')}>331            {trials.length ? (332              <>333                <TrialTable334                  rows={trials}335                  summary={336                    <>337                      Showing {fmtInt(tp.from)}–{fmtInt(tp.to)} of {fmtInt(trialCounts.active)} active studies338                    </>339                  }340                />341                <Pager total={trialCounts.active} pageSize={tp.pageSize} page={tp.page} hrefFor={(p) => href({ tPage: p > 1 ? p : '' }, 'trials')} label="Trial pages" noun="studies" />342                <p className="mt-2 text-[12px] text-ink-3">A study listed here tests a linked drug in a linked cancer; it does not necessarily select participants on this biomarker.</p>343              </>344            ) : (345              <EmptyState compact knows={[{ label: 'Trials explorer', href: '/trials' }]}>346                {reason ?? 'No active registered study combines a derived drug with an associated cancer.'}347              </EmptyState>348            )}349          </Section>350351          <Section id="publications" kicker="Literature" title={`Linked publications (${fmtInt(pTotal)})`} description={pTotal ? `Publications linked to the scope ${lit.entityType === 'variant' ? 'variant(s)' : 'gene(s)'} through PubMed entity edges; ${PUBLICATION_PAGE_SIZE} per page, newest first.` : undefined}>352            {pubs.length ? (353              <>354                <PublicationList355                  rows={pubs}356                  summary={357                    <>358                      Showing {fmtInt(pp.from)}–{fmtInt(pp.to)} of {fmtInt(pTotal)} publications359                    </>360                  }361                />362                <Pager total={pTotal} pageSize={pp.pageSize} page={pp.page} hrefFor={(p) => href({ pPage: p > 1 ? p : '' }, 'publications')} label="Publication pages" noun="publications" />363              </>364            ) : (365              <EmptyState compact>{reason ?? `No publication is linked to the scope ${lit.entityType === 'variant' ? 'variants' : 'genes'} yet.`}</EmptyState>366            )}367          </Section>368        </div>369370        <aside className="space-y-8">371          <Section id="measurement" kicker="What is measured" title="Measurement" level={3}>372            <KV373              items={[374                { k: 'Kind', v: kindLabel(b.kind) },375                { k: 'Assays', v: m.assays?.length ? m.assays.join(', ') : null },376                { k: 'Scoring', v: m.scoring },377                { k: 'Notes', v: m.notes },378                { k: 'NCIt concept', v: b.ncit_code ? (379                    <a className="ci-link inline-flex items-center gap-1" href={EVS(b.ncit_code)} target="_blank" rel="noopener noreferrer">380                      {m.ncit?.name ?? b.ncit_code} <span className="ci-mono text-ink-3">{b.ncit_code}</span> <ExternalLink className="h-3 w-3" aria-hidden />381                    </a>382                  ) : null },383                { k: 'Genes', v: genes.length ? (384                    <span>385                      {genes.map((g, i) => (386                        <span key={g.id}>387                          {i > 0 ? ', ' : ''}388                          <Link className="ci-link ci-mono" href={`/gene/${g.symbol}`}>389                            {g.symbol}390                          </Link>391                          {g.name ? <span className="text-ink-3"> {g.name}</span> : null}392                        </span>393                      ))}394                    </span>395                  ) : <span className="text-ink-3">none (see notes)</span> },396                { k: 'Variant anchors', v: variants.length ? (397                    <span>398                      {variants.map((v, i) => (399                        <span key={v.id}>400                          {i > 0 ? ', ' : ''}401                          <Link className="ci-link" href={`/variant/${v.slug}`}>402                            {v.gene_symbol ? `${v.gene_symbol} ` : ''}403                            {v.name}404                          </Link>405                        </span>406                      ))}407                    </span>408                  ) : null },409                { k: 'Indication phrases', v: m.indicationTerms?.length ? <span className="text-[12.5px]">{m.indicationTerms.join(' · ')}</span> : null },410              ]}411            />412            {m.sources?.length ? (413              <div className="mt-3">414                <p className="ci-kicker mb-1">Sources</p>415                <ul className="m-0 list-none space-y-0.5 p-0 text-[12.5px]">416                  {m.sources.map((s) => (417                    <li key={s.url}>418                      <a className="ci-link inline-flex items-center gap-1" href={s.url} target="_blank" rel="noopener noreferrer">419                        {s.label} <ExternalLink className="h-3 w-3" aria-hidden />420                      </a>421                    </li>422                  ))}423                </ul>424              </div>425            ) : null}426            <div className="mt-3 flex flex-wrap items-center gap-1.5 text-[12px] text-ink-3">427              <ClaimBadge kind="curated" />428              <SourceBadge p={{ sourceSlug: 'ncit-evs', sourceName: 'NCI Thesaurus (NCIt)', dataset: m.verification ? `EVS REST API, NCIt ${m.verification.ncitVersion}` : undefined, retrievedAt: m.verification?.verifiedAt ?? null, layer: 'canonical', note: 'Identity metadata curated by CancerIndex; the NCIt code was fetched from the EVS REST API.' }} />429            </div>430            <Freshness dataUpdatedAt={b.updated_at} sourceVersion={m.verification ? `NCIt ${m.verification.ncitVersion}` : null} extra={m.verification ? `code verified ${m.verification.verifiedAt}` : undefined} />431          </Section>432          <Note>433            A biomarker page describes what a test measures and lists the source records that mention it. It does not grade clinical utility, set thresholds or give individual guidance. Derived counts follow rule <span className="ci-mono">{BIOMARKER_LINKS_FORMULA}</span> —{' '}434            <Link className="ci-link" href="/methodology#biomarkers">435              methodology436            </Link>437            .438          </Note>439        </aside>440      </div>441    </article>442  );443}444